module FMC
    implicit none
    real(8), pointer, dimension(:,:) :: mt_fmc, mt_fmcLU
    real(8), private, pointer, dimension(:) :: psi_fmc, q_fmc
    real(8), private, pointer, dimension(:,:) :: sol,ps
    real(8), private, pointer, dimension(:,:) :: mm1, mm2, mmNF, mmA, pse, psa
    integer, private, parameter :: fedg = 85, favg = 86, fDFedg = 1085, fDFavg = 1086
    
    integer, private, parameter :: fsrf=201, fsrf2=202, fAbs=203, fA=204, fE=205, fNuF=206, fF=207, fMTFMC=208, fMTFMCOFF=209
    integer, private, parameter :: fRL1FMC=210, fRL2FMC=211
    integer, private :: size, np
    integer, parameter, private :: TYPE_EDG=1, TYPE_AVG=2
    real(8), private, pointer, dimension(:,:) :: fcnF, fcnE, fcnA
    integer, private, pointer, dimension(:) :: tcmpl
contains

subroutine init_fmc
    include "pspec.FI"
    include "xsec.FI"
    include "arrays.FI"
    include "accm.FI"
    integer :: i 
    if (ng .gt. 1) return
!    np = totmesh+1
    np = totm_cmfd+1
    size = np*ng
!    allocate(mt_fmc(size,size))
!    allocate(mt_fmcLU(size,size))
    allocate(mt_fmc(3,size))
    allocate(mt_fmcLU(3,size))
    allocate(sol(size, ng))
!    allocate(ps(size, ng))
    allocate(psi_fmc(size))
    allocate(q_fmc(size))
    allocate(fcnF(np,ng), fcnE(np,ng), fcnA(np,ng))
    
    
    allocate(mm1(size,ng))
    allocate(mm2(size,ng))
    allocate(tcmpl(2*totm_cmfd))
    
    ! assign proper composition
    do i=1, totm_cmfd
        tcmpl(2*i-1) = complist(rcf*(i-1)+1)
        tcmpl(2*i)   = complist(rcf*i)
    enddo
    
    open(fedg, file='FMCEDG.txt', status='unknown')
    open(favg, file='FMCAVG.txt', status='unknown')
    open(fDFedg, file='FMCDFEDG.txt', status='unknown')
    open(fDFavg, file='FMCDFAVG.txt', status='unknown')
    if (NMVWND .eq. 1) then
!        mm1 => mmt1st
!        mm2 => mmt2nd
        mmNF => mmtNuF
        mmA => mmtAbsr
        pse => phi_s
        psa => phi_sa
    else
!        mm1 => mmt1stAC
!        mm2 => mmt2ndAC
        mmNF => mmtNuFAC
        mmA => mmtAbsrAC
        pse => phisAC
        psa => phisaAC
    endif
    mt_fmc= 0
#ifdef _COEFF
!    open(fsrf, file="FMC_PHIS.txt", status="unknown")
!    open(fsrf2, file="FMC_PHIS2.txt", status="unknown")
!    open(fAbs, file="FMC_MMABS.txt", status="unknown")
!    open(fA, file="FMC_A.txt", status="unknown")
!    open(fE, file="FMC_E.txt", status="unknown")
!    open(fNuF, file="FMC_MMNUF.txt", status="unknown")
!    open(fF, file="FMC_F.txt", status="unknown")
!    open(fMTFMC, file="MT_FMC.txt", status="unknown")
!    open(fMTFMCOFF, file="MT_FMCOF.txt", status="unknown")
!    open(fRL1FMC, file="MT_R1FMC.txt", status="unknown")
!    open(fRL2FMC, file="MT_R2FMC.txt", status="unknown")
#endif    
end subroutine

function checkflux
    logical :: checkflux
    integer :: i
    checkflux = .true.
    do i=1, np
        if (psa(i,1) .eq. 0._8) then
            checkflux = .false.
            return
        endif
    enddo
end function

subroutine slove_fmc_tdiag(ifst)
    use LU_tdiag
    use powermethod
    include "pspec.FI"
    include "arrays.FI"
    include "xsec.FI"
    include "stsol.FI"
    real(8) :: k, err, dr
    real(8) :: s1, s2, k1, k2
    real(8), dimension(np) :: A, E
    real(8), dimension(0:np+1) :: mt
    real(8) :: rnorm, fsr, test1, test2
    integer :: iter, i,j
    logical, save :: first = .true.
    real(8) :: relfl1(np), relfl2(np-1)
    logical :: ifst


!    fsr = sum(psi_f)
    fsr = 1._8
    if (ng .gt. 1) return
    
    k1=  1.0_8
    k2=  1.0_8
    sol = psa

!   condense 1st and 2nd moment of surface flux
    mm1(1,1) = mmt1st(1,1)
    mm2(1,1) = mmt2nd(1,1)
    do i=1, size-1
        mm1(i+1,1)=mmt1st(1+rcf*i,1)
        mm2(i+1,1)=mmt2nd(1+rcf*i,1)
    enddo

    
#ifdef _AFCONVERGE
    if (first) then
        open(601, file='AF_cvg.txt', status='old')
        read(601, *) fcnA(:,1)
        read(601, *) fcnF(:,1)
        read(601, *) fcnE(:,1)
        close(601)
        first = .false.
    endif
    do i=1, np
        fcnA(i,1) = mmA(i,1)/psa(i,1)
!        fcnF(i,1) = mmNF(i,1)/psa(i,1)
        fcnE(i,1) = mm2(i,1)/psa(i,1)
    end do
#else
    do i=1, np
        if (psa(i,1) .gt. 0._8) then
            fcnA(i,1) = mmA(i,1)/psa(i,1)
            fcnE(i,1) = mm2(i,1)/psa(i,1)
            fcnF(i,1) = mmNF(i,1)/psa(i,1)
        else
            fcnA(i,1) = 0._8
            fcnE(i,1) = 0._8
            fcnF(i,1) = 0._8
            sol (i,1) = 0._8
        endif
    end do
#endif    

!    call make_mt_fmc_tdiag_DF(type_edg)
!    call powermethodWT(np, 3, mt_fmcLU, sol, psi_fmc, makeFS, rhs_tdiag_wldt, FMC_shift_wldt, solve_LU, ccpsi, k1, err, dr, iter)
!    rnorm = fsr/sum(psi_fmc)
!    sol=sol*rnorm
!    write(fDFedg, '(2000(e11.5,1x))') k1,(sol(i,1),i=1,np)
!
!    call make_mt_fmc_tdiag_DF(type_avg)
!    call powermethodWT(np, 3, mt_fmcLU, sol, psi_fmc, makeFS, rhs_tdiag_wldt, FMC_shift_wldt, solve_LU, ccpsi, k1, err, dr, iter)
!    rnorm = fsr/sum(psi_fmc)
!    sol=sol*rnorm
!    write(fDFavg, '(2000(e11.5,1x))') k1,(sol(i,1),i=1,np)

!    call make_mt_fmc_tdiag(TYPE_EDG)
!    call powermethodWT(np, 3, mt_fmcLU, sol, psi_fmc, makeFS, rhs_tdiag_wldt, FMC_shift_wldt, solve_LU, ccpsi, k1, err, dr, iter)
!    rnorm = fsr/sum(psi_fmc)
!    sol=sol*rnorm
!!    gtally_temp = sol(mpeak,1)
!    write(fedg, '(2000(e11.5,1x))') k1,(sol(i,1),i=1,np)

    
    call make_mt_fmc_tdiag(TYPE_AVG)
    call powermethodWT(np, 3, mt_fmcLU, sol, psi_fmc, makeFS, rhs_tdiag_wldt, FMC_shift_wldt, solve_LU, ccpsi, k2, err, dr, iter)
    rnorm = fsr/sum(psi_fmc)
    sol=sol*rnorm
    write(favg, '(2000(e11.5,1x))'), k2, (sol(i,1),i=1,np)
#ifdef _COEFF
    write(fsrf,     '(2000(e11.5,1x))'), (psa(i,1),i=1,np   )
    write(fsrf2,    '(2000(e11.5,1x))'), (mm2(i,1),i=1,np   )
    write(fAbs,     '(2000(e11.5,1x))'), (mmA(i,1),i=1,np   )
    write(fA,       '(2000(e11.5,1x))'), (fcnA(i,1),i=1,np  )
    write(fE,       '(2000(e11.5,1x))'), (fcnE(i,1),i=1,np  )
    write(fNuF,     '(2000(e11.5,1x))'), (mmNF(i,1),i=1,np  )
    write(fF,       '(2000(e11.5,1x))'), (fcnF(i,1),i=1,np  )
    write(fMTFMC,   '(2000(e11.5,1x))'), (mt_fmc(2,i),i=1,np)
    write(fMTFMCOFF,'(2000(e11.5,1x))'), (mt_fmc(1,i),i=2,np)
    
    i=1
    relfl1(i) =  -mt_fmc(3,i)/mt_fmc(2,i)
    do i=1, np-1
        relfl1(i) =-( mt_fmc(1,i) + mt_fmc(3,i) )/mt_fmc(2,i)
        relfl2(i) = -mt_fmc(3,i)/mt_fmc(2,i)
    end do
    relfl1(i) = -mt_fmc(1,i)/mt_fmc(2,i)
!    write(fRL1FMC,   '(2000(e11.5,1x))') (relfl1(i),i=1,np)    
!    write(fRL2FMC,   '(2000(e11.5,1x))') (relfl2(i),i=2,np-1)    
#endif

    ! for feedback
    adj_fmc = 0
    i=1
    adj_fmc = psi_fmc
!    adj_fmc(i) = psi_fmc(i)
!    do i=1, np-2
!        if (xnuf(complist(i),1)>0) then
!            adj_fmc(i) = adj_fmc(i) + 0.5_8*psi_fmc(i+1)
!        else 
!            adj_fmc(i+1) = adj_fmc(i+1) + 0.5_8*psi_fmc(i+1)
!        endif
!        if (xnuf(complist(i+1),1)>0) then
!            adj_fmc(i+1) = adj_fmc(i+1) + 0.5_8*psi_fmc(i+1)
!        else 
!            adj_fmc(i) = adj_fmc(i) + 0.5_8*psi_fmc(i+1)
!        endif
!        
!    end do
!    adj_fmc(i-1) = adj_fmc(i) + psi_fmc(i)
!    test1 = sum(adj_fmc)
!    test2 = sum(psi_fmc)
    adj_fmc=adj_fmc/sum(adj_fmc)
!    open (1005, file = "MFMC.txt", status="unknown")
!    do j=1, np
!        mt = 0
!        mt(j-1) = mt_fmc(1,j)
!        mt(j) = mt_fmc(2,j)
!        mt(j+1) = mt_fmc(3,j)
!        
!        write(1005,      '(2000(e11.5,1x))') (mt(i),i=1,np)
!    end do
!    close(1005)


!    write(*,*)
!    write(*,'(f7.5)') k2
    if (ifst) then
        if (NMVWND .eq. 1) then
            stfmc(0)=stfmc(0)+k2
            stsqfmc(0)=stsqfmc(0)+k2**2
            do i=1, np
                stfmc(i) = stfmc(i) + sol(i,1)
                stsqfmc(i) = stsqfmc(i) + sol(i,1)**2
            enddo
        else
            stfmc(0)=k2
            do i=1, np
                stfmc(i) = sol(i,1)
            enddo
        endif
    endif
    
end subroutine

subroutine rhs_tdiag_wldt(k,q)
    include "pspec.FI"
    include "xsec.FI"
    include "arrays.FI"
    real(8), intent(in) :: k
    real(8), dimension(:), intent(out) :: q
    integer :: i,  g, l, gp
    q =0
    do i=1, np
        q(i) =psi_fmc(i)/k
    end do
end subroutine

subroutine rhs_tdiag(g,k)
    include "pspec.FI"
    include "arrays.FI"
    include "xsec.FI"
    integer, intent(in) :: g
    real(8), intent(in) :: k
    integer :: i, gp
    q_fmc =0
    do i=1, np
        q_fmc(i) = psi_fmc(i)/k
    end do
end subroutine

subroutine FMC_shift_wldt(ke)
    use LU_tdiag
    use util_cmfd
    implicit none    
    include "xsec.FI"
    include "pspec.FI"
    include "arrays.FI"
    real(8), intent(in) :: ke
    integer :: i, l, m, g, gp
    real(8) :: ker
    ker = 1._8/ke
    mt_fmclu = mt_fmc
    do i=1, np
        mt_fmclu(2,i) = mt_fmclu(2,i)-ker*fcnF(i,1)
    end do    
    call LU_factorize(NP, mt_fmclu)
end subroutine

subroutine make_mt_fmc_tdiag(type_fmc)
    use LU_tdiag
    include "pspec.FI"
    include "xsec.FI"
    include "arrays.FI"
    integer, intent(in) :: type_fmc
    integer :: i, g, l
    real(8) :: A, B, E, F, xTR, ci, cip
    real(8) :: leak
    real(8), pointer, dimension(:) :: hc
    real(8) :: xtot1l, xtot1r, xtot2l, xtot2r
    hc=>h_cmfd

    if ( type_fmc .eq. TYPE_EDG) then
        ps => pse
    else
        ps => psa
    endif
        
    
    do g=1, ng
        i=1
        xtot2l =  Xtot(tcmpl(2*i-1),g)
        xtot2r =  Xtot(tcmpl(2*i-0),g)

        if (ps(i,g)>0) then
            B = mm1(i,g)/ps(i,g)
        else
            B = 0
        endif
        A = fcnA(i,g)
        E = fcnE(i,g)
        mt_fmc(2,i) =  B + 1._8/xtot2l/hc(i)*E+A
        
        E = fcnE(i+1,g)
        mt_fmc(3,i) = -1._8/xtot2r/hc(i)*E

        ci = cip
        do i=2, np-1
            xtot1l =  Xtot(tcmpl(2*i-3),g)
            xtot1r =  Xtot(tcmpl(2*i-2),g)
            xtot2l =  Xtot(tcmpl(2*i-1),g)
            xtot2r =  Xtot(tcmpl(2*i-0),g)
            
            A = fcnA(i,g)
            E = fcnE(i,g)
            mt_fmc(2,i) =  (1._8/xtot1r/hc(i-1)+1._8/xtot2l/hc(i))*E+A

            E = fcnE(i-1,g)
            mt_fmc(1,i)= -1._8/xtot1l/hc(i-1)*E
            
            E = fcnE(i+1,g)
            mt_fmc(3,i) = -1._8/xtot2r/hc(i)*E
        end do
        
        xtot1l =  Xtot(tcmpl(2*i-3),g)
        xtot1r =  Xtot(tcmpl(2*i-2),g)

        if(ps(i,g)>0)then
            B = mm1(i,g)/ps(i,g)
        else    
            B = 0
        endif
        A = fcnA(i,g)
        E = fcnE(i,g)
        mt_fmc(2,i) = B+1._8/xtot1r/hc(i-1)*E+A
        
        E = fcnE(i-1,g)
        mt_fmc(1,i) = -1._8/xtot1l/hc(i-1)*E
    enddo
!    do i=1, np
!        if (fcnE(i,1) .eq. 0) then
!            mt_fmc(:,i) = 0
!        endif
!    enddo
    mt_fmcLU = mt_fmc
    call LU_factorize(size, mt_fmcLU)
end subroutine

subroutine make_mt_fmc_tdiag_old(type_fmc)
    use LU_tdiag
    include "pspec.FI"
    include "xsec.FI"
    include "arrays.FI"
    integer, intent(in) :: type_fmc
    integer :: i, g, l
    real(8) :: A, B, E, F, xTR, ci, cip
    real(8) :: leak
    real(8), pointer, dimension(:) :: hc
    hc=>h_cmfd

    if ( type_fmc .eq. TYPE_EDG) then
        ps => pse
    else
        ps => psa
    endif
        
    
    do g=1, ng
        i=1
        l = (g-1)*np + i
        xTR = Xtot(complist(l),g)
#ifdef _LANISO
        xTR = xTR-0.1_8
#endif
        cip = 1._8/(xTR*hc(l))

        if (ps(i,g) .eq. 0) then
            mt_fmc(2,l) =  B + cip*E+A
        else
            B = mm1(i,g)/ps(i,g)
            A = fcnA(i,g)
            E = fcnE(i,g)
            mt_fmc(2,l) =  B + cip*E+A
        endif
        
        E = fcnE(l+1,g)
        mt_fmc(3,l) = -cip*E

!        ! functionals        
!        fcnF(i,g)=mmNF(i,g)/ps(i,g)
!        fcnE(i,g)=E
!        fcnA(i,g)=A
        
        
        ci = cip
        do i=2, np-1
            l = (g-1)*totmesh + i
            xTR = Xtot(complist(l),g)
#ifdef _LANISO
            xTR = xTR-0.1_8
#endif
            cip = 1._8/(xTR*hc(i))
            
            A = fcnA(i,g)
            E = fcnE(i,g)
            mt_fmc(2,l) =  (ci+cip)*E+A
            leak = (ci+cip)*E*ps(i,g)

            E = fcnE(i-1,g)
            mt_fmc(1,l)= -ci*E
            leak = leak -ci*E*ps(i-1,g)
            
            E = fcnE(i+1,g)
            mt_fmc(3,l) = -cip*E
            leak = leak -cip*E*ps(i+1,g)
            
!            ! functionals        
!            fcnF(i,g)=mmNF(i,g)/ps(i,g)
!            fcnE(i,g)=E
!            fcnA(i,g)=A

            ci = cip
        end do
        l = (g-1)*totmesh + i
        if (ps(i,g) .eq. 0) then
            mt_fmc(2,l) =  0
        else
            B = mm1(i,g)/ps(i,g)
            A = fcnA(i,g)
            E = fcnE(i,g)
            mt_fmc(2,l) = B+ci*E+A
        endif
        
        E = fcnE(i-1,g)
        mt_fmc(1,l) = -ci*E

!        ! functionals        
!        fcnF(i,g)=mmNF(i,g)/ps(i,g)
!        fcnE(i,g)=E
!        fcnA(i,g)=B
    enddo
    mt_fmcLU = mt_fmc
    call LU_factorize(size, mt_fmcLU)
end subroutine


subroutine make_mt_fmc_tdiag_df(type_fmc)
    use LU_tdiag
    include "pspec.FI"
    include "xsec.FI"
    include "arrays.FI"
    integer, intent(in) :: type_fmc
    integer :: i, g, l
    real(8) :: A, B, E, F, xTR, ci, cip
    real(8), pointer, dimension(:) :: hc
    hc=>h_cmfd

    if ( type_fmc .eq. TYPE_EDG) then
        ps => pse
    else
        ps => psa
    endif
        
    
    do g=1, ng
        i=1
        l = (g-1)*np + i
        xTR = Xtot(complist(i),g)
#ifdef _LANISO
        xTR = xTR-0.1_8
#endif
        cip = Xdif(complist(i),g)/hc(i)

        if (ps(i,g) .eq. 0) then
            mt_fmc(2,l) =  B + cip*E+A
        else
            B = mm1(i,g)/ps(i,g)
            A = fcnA(i,g)
            E = phi_s(i,g)/ps(i,g)
            mt_fmc(2,l) =  B + cip*E+A
        endif
        
        E = phi_s(i+1,g)/ps(i+1,g)
        mt_fmc(3,l) = -cip*E

!        ! functionals        
!        fcnF(i,g)=mmNF(i,g)/ps(i,g)
!        fcnE(i,g)=E
!        fcnA(i,g)=A
        
        
        ci = cip
        do i=2, np-1
            l = (g-1)*totmesh + i
            xTR = Xtot(complist(i),g)
#ifdef _LANISO
            xTR = xTR-0.1_8
#endif
            cip = Xdif(complist(i),g)/hc(i)
            
            A = fcnA(i,g)
            E = phi_s(i,g)/ps(i,g)
            mt_fmc(2,l) =  (ci+cip)*E+A

            E = phi_s(i-1,g)/ps(i-1,g)
            mt_fmc(1,l)= -ci*E

            E = phi_s(i+1,g)/ps(i+1,g)
            mt_fmc(3,l) = -cip*E
            
!            ! functionals        
!            fcnF(i,g)=mmNF(i,g)/ps(i,g)
!            fcnE(i,g)=E
!            fcnA(i,g)=A

            ci = cip
        end do
        l = (g-1)*totmesh + i
        if (ps(i,g) .eq. 0) then
            mt_fmc(2,l) =  0
        else
            B = mm1(i,g)/ps(i,g)
            A = fcnA(i,g)
            E = phi_s(i,g)/ps(i,g)
            mt_fmc(2,l) = B+ci*E+A
        endif
        
        E = phi_s(i-1,g)/ps(i-1,g)
        mt_fmc(1,l) = -ci*E

!        ! functionals        
!        fcnF(i,g)=mmNF(i,g)/ps(i,g)
!        fcnE(i,g)=E
!        fcnA(i,g)=B
    enddo
    mt_fmcLU = mt_fmc
    call LU_factorize(size, mt_fmcLU)
end subroutine


subroutine makeFS
    include "pspec.FI"
    include "arrays.FI"
    include "xsec.FI"
    integer :: i,  g, l, gp
    do g=1, ng
        do i=1, np
            l = (g-1)*np + i
!            psi_fmc(l) = mmNF(i, g)/ps(i,g)*sol(i,g)
            psi_fmc(l) = fcnF(i, g)*sol(i,g)
        end do
    end do
end subroutine

!subroutine slove_fmc
!    include "pspec.FI"
!    real(8) :: k, err, dr
!    integer :: iter
!    k=  1._8
!    call make_mt_fmc
!    call powermethod_wldt(np, mt_fmcLU, makeFS, rhs, shift_fmc, ccpsi, sol, psi_fmc, k, err, dr, iter)
!
!end subroutine
!
!subroutine make_mt_fmc
!    use LU_general
!    include "pspec.FI"
!    include "xsec.FI"
!    include "arrays.FI"
!    integer :: i, g, l
!    real(8) :: A, B, E, F, xTR, ci, cip
!    
!    do g=1, ng
!        i=1
!        l = (g-1)*np + i
!        xTR = Xtot(complist(l),g)
!#ifdef _LANISO
!        xTR = xTR-0.1_8
!#endif
!        cip = 1._8/(xTR*h(l))
!
!        B = mm1(i,g)/phi_s(i,g)
!        A = mmA(i,g)/phi_s(i,g)
!        E = mm2(i,g)/phi_s(i,g)
!        mt_fmc(l,l) =  B + cip*E+A
!        E = mm2(l+1,g)/phi_s(l+1,g)
!        mt_fmc(l+1,l) = -cip*E
!        
!        ci = cip
!        do i=2, np-1
!            l = (g-1)*totmesh + i
!            xTR = Xtot(complist(l),g)
!#ifdef _LANISO
!            xTR = xTR-0.1_8
!#endif
!            cip = 1._8/(xTR*h(i))
!            
!            A = mmA(i,g)/phi_s(i,g)
!            E = mm2(i,g)/phi_s(i,g)
!            mt_fmc(l,l) =  (ci+cip)*E+A
!
!            E = mm2(i-1,g)/phi_s(i-1,g)
!            mt_fmc(l-1,l)= -ci*E
!
!            E = mm2(i+1,g)/phi_s(i+1,g)
!            mt_fmc(l+1,l) = -cip*E
!            
!            ci = cip
!        end do
!        l = (g-1)*totmesh + i
!        B = mm1(i,g)/phi_s(i,g)
!        A = mmA(i,g)/phi_s(i,g)
!        E = mm2(i,g)/phi_s(i,g)
!        mt_fmc(l,l) = B+ci*E+A
!        
!        E = mm2(i-1,g)/phi_s(i-1,g)
!        mt_fmc(l-1,l) = -ci*E
!    enddo
!    mt_fmcLU = mt_fmc
!    call LU_factorize(size, mt_fmcLU)
!end subroutine
!
!subroutine shift_fmc(ke)
!    use LU_general
!    include "pspec.FI"
!    include "xsec.FI"
!    include "arrays.FI"
!    real(8), intent(in) :: ke
!    real(8) :: kr
!    integer :: g, i, l
!    kr = 1._8/ke
!    mt_fmcLU = mt_fmc
!    do g=1, ng
!        do i=1, np
!            l = (g-1)*np + i
!            mt_fmcLU(l,l) = mt_fmcLU(l,l)-kr*mmNF(i, g)/phi_s(i,g)
!        end do
!    enddo
!    call LU_factorize(size, mt_fmcLU)
!end subroutine
!
!
!subroutine rhs(k, q)
!    include "pspec.FI"
!    include "arrays.FI"
!    include "xsec.FI"
!    real(8), intent(in) :: k
!    real(8), dimension(:), intent(out) :: q
!    integer :: i,  g, l, gp
!    q =0
!    do g=1, ng
!        do i=1, np
!            l = (g-1)*np + i
!            q(l) = mmNF(i, g)/phi_s(i,g)/k
!        end do
!    end do
!end subroutine
!

end module